package org.jenkinsci.plugins.p4scm;

import hudson.FilePath;
import hudson.Launcher;
import hudson.remoting.FastPipedInputStream;
import hudson.remoting.FastPipedOutputStream;
import hudson.util.StreamTaskListener;

import java.io.IOException;
import java.util.Map;
import jenkins.model.Jenkins;

import com.tek42.perforce.PerforceException;

public class P4DefaultExecutor extends AbstractP4Executor {
    
    public P4DefaultExecutor(Launcher launcher, Map<String, String> envMap, FilePath filePath) {
        super(launcher, envMap, filePath);
    }

    @SuppressWarnings("deprecation")
    @Override
    public void exec(String[] cmd) throws PerforceException {
        
        try {
            // ensure we actually have a valid launcher
            if(null == launcher) {
                launcher = Jenkins.getInstance().createLauncher(new StreamTaskListener(System.out));
            }
            
            //TODO: why need to create a connection between input and output
            // jenkinsOut -> p4In -> reader
            JenkinsPipedOutputStream jenkinsOut = new JenkinsPipedOutputStream();
            FastPipedInputStream p4In = new FastPipedInputStream(jenkinsOut);
            input = p4In;
            
            // jenkinsIn <- p4Out <- writer
            FastPipedInputStream jenkinsIn = new FastPipedInputStream();
            FastPipedOutputStream p4Out = new FastPipedOutputStream(jenkinsIn);
            output = p4Out;
            
            currentProcess = launcher.launch().cmds(cmd).envs(env).stdin(jenkinsIn).stdout(jenkinsOut).pwd(filePath).start();
            
            jenkinsOut.closeOnProcess(currentProcess);
            
        } catch(IOException e) {
            //try to close all the pipes before throwing an exception
            close();
            throw new PerforceException("Could not run perforce command.", e);
        }
    }
}
